home *** CD-ROM | disk | FTP | other *** search
/ Aminet 20 / Aminet 20 (1997)(GTI - Schatztruhe)[!][Aug 1997].iso / Aminet / comm / www / HTP.lha / HTP / source / jpeg.c < prev    next >
C/C++ Source or Header  |  1997-06-21  |  5KB  |  239 lines

  1. /*
  2. //
  3. // jpeg.c
  4. //
  5. // JPEG FIF (File Interchange Format) support functions
  6. //
  7. // Copyright (c) 1995-96 Jim Nelson.  Permission to distribute
  8. // granted by the author.  No warranties are made on the fitness of this
  9. // source code.
  10. // Amiga version - 1997 - Geert Bevin
  11. //
  12. */
  13.  
  14. #include "htp.h"
  15.  
  16. /*
  17. // a great deal of this code was ripped off wholesale from the Independent
  18. // JPEG Group's sample source code, obtainable from any SimTel mirror under
  19. // msdos/graphics/jpegsrc6.zip
  20. */
  21.  
  22. /*
  23. // JPEG markers
  24. */
  25. #define M_SOF0  0xC0        /* Start Of Frame N */
  26. #define M_SOF1  0xC1            /* N indicates which compression process */
  27. #define M_SOF2  0xC2            /* Only SOF0-SOF2 are now in common use */
  28. #define M_SOF3  0xC3
  29. #define M_SOF5  0xC5            /* NB: codes C4 and CC are NOT SOF markers */
  30. #define M_SOF6  0xC6
  31. #define M_SOF7  0xC7
  32. #define M_SOF9  0xC9
  33. #define M_SOF10 0xCA
  34. #define M_SOF11 0xCB
  35. #define M_SOF13 0xCD
  36. #define M_SOF14 0xCE
  37. #define M_SOF15 0xCF
  38. #define M_SOI   0xD8            /* Start Of Image (beginning of datastream) */
  39. #define M_EOI   0xD9            /* End Of Image (end of datastream) */
  40. #define M_SOS   0xDA            /* Start Of Scan (begins compressed data) */
  41. #define M_APP0  0xE0
  42. #define M_COM   0xFE            /* COMment */
  43.  
  44. BOOL JpegReadByte(FILE *file, BYTE *b)
  45. {
  46.     int i;
  47.  
  48.     if((i = fgetc(file)) == EOF)
  49.     {
  50.         DEBUG_PRINT(("unable to read byte from JFIF file"));
  51.         return FALSE;
  52.     }
  53.  
  54.     *b = (BYTE) i;
  55.  
  56.     return TRUE;
  57. }
  58.  
  59. BOOL JpegReadWord(FILE *file, WORD *w)
  60. {
  61.     int hi;
  62.     int lo;
  63.  
  64.     /* words are kept in MSB format */
  65.     if((hi = fgetc(file)) == EOF)
  66.     {
  67.         DEBUG_PRINT(("unable to read high byte from JFIF file"));
  68.         return FALSE;
  69.     }
  70.  
  71.     if((lo = fgetc(file)) == EOF)
  72.     {
  73.         DEBUG_PRINT(("unable to read low byte from JFIF file"));
  74.         return FALSE;
  75.     }
  76.  
  77.     *w = MAKE_WORD(hi, lo);
  78.  
  79.     return TRUE;
  80. }
  81.  
  82. BOOL JpegFirstMarker(FILE *file)
  83. {
  84.     BYTE flag;
  85.     BYTE marker;
  86.  
  87.     /* move to the beginning of the file */
  88.     if(fseek(file, 0, SEEK_SET) != 0)
  89.     {
  90.         DEBUG_PRINT(("unable to seek to start of JFIF file"));
  91.         return FALSE;
  92.     }
  93.  
  94.     /* look for the start of image marker */
  95.     if(JpegReadByte(file, &flag) == FALSE)
  96.     {
  97.         return FALSE;
  98.     }
  99.  
  100.     if(JpegReadByte(file, &marker) == FALSE)
  101.     {
  102.         return FALSE;
  103.     }
  104.  
  105.     /* start of image? */
  106.     if((flag != 0xFF) || (marker != M_SOI))
  107.     {
  108.         return FALSE;
  109.     }
  110.  
  111.     return TRUE;
  112. }
  113.  
  114. BOOL JpegNextMarker(FILE *file, BYTE *marker)
  115. {
  116.     BYTE flag;
  117.     BOOL ok;
  118.  
  119.     /* move file pointer to next 0xFF flag */
  120.     while((ok = JpegReadByte(file, &flag)) == TRUE)
  121.     {
  122.         if(flag == 0xFF)
  123.         {
  124.             break;
  125.         }
  126.     }
  127.  
  128.     if(ok == FALSE)
  129.     {
  130.         return FALSE;
  131.     }
  132.  
  133.     /* extra 0xFF flags are legal as padding, so move past them */
  134.     while((ok = JpegReadByte(file, marker)) == TRUE)
  135.     {
  136.         if(*marker != 0xFF)
  137.         {
  138.             break;
  139.         }
  140.     }
  141.  
  142.     /* exit condition really depends if a good marker was found */
  143.     return ok;
  144. }
  145.  
  146. BOOL JpegFormatFound(FILE *file)
  147. {
  148.     BYTE marker;
  149.     char signature[8];
  150.  
  151.     if(JpegFirstMarker(file) == FALSE)
  152.     {
  153.         return FALSE;
  154.     }
  155.  
  156.     if(JpegNextMarker(file, &marker) == FALSE)
  157.     {
  158.         return FALSE;
  159.     }
  160.  
  161.     /* should see an APP0 marker */
  162.     if(marker != M_APP0)
  163.     {
  164.         return FALSE;
  165.     }
  166.  
  167.     /* file format is now pointing to JFIF header ... skip two bytes and */
  168.     /* look for the signature */
  169.     if(fseek(file, 2, SEEK_CUR) != 0)
  170.     {
  171.         DEBUG_PRINT(("unable to seek to start of JFIF file"));
  172.         return FALSE;
  173.     }
  174.  
  175.     if(fread(signature, 1, 5, file) != 5)
  176.     {
  177.         DEBUG_PRINT(("unable to read JFIF signature from file"));
  178.         return FALSE;
  179.     }
  180.  
  181.     /* it all comes down to the signature being present */
  182.     return (strcmp(signature, "JFIF") == 0) ? TRUE : FALSE;
  183. }
  184.  
  185. BOOL JpegReadDimensions(FILE *file, WORD *height, WORD *width)
  186. {
  187.     BYTE marker;
  188.  
  189.     /* make sure we can find the first marker */
  190.     if(JpegFirstMarker(file) == FALSE)
  191.     {
  192.         return FALSE;
  193.     }
  194.  
  195.     /* read file looking for SOF (start of frame) ... when it or */
  196.     /* or SOS (start of scan, the compressed data) is reached, stop */
  197.     while(JpegNextMarker(file, &marker) == TRUE)
  198.     {
  199.         /* if SOS, stop */
  200.         if(marker == M_SOS)
  201.         {
  202.             DEBUG_PRINT(("JFIF SOS marker found before SOF marker"));
  203.             break;
  204.         }
  205.  
  206.         /* if not SOF, continue */
  207.         if((marker < M_SOF0) || (marker > M_SOF15))
  208.         {
  209.             continue;
  210.         }
  211.  
  212.         /* start of frame found ... process the dimension information */
  213.         /* seek past the next three bytes, useless for this application */
  214.         if(fseek(file, 3, SEEK_CUR) != 0)
  215.         {
  216.             return FALSE;
  217.         }
  218.  
  219.         /* read the height and width and get outta here */
  220.         if(JpegReadWord(file, height) == FALSE)
  221.         {
  222.             return FALSE;
  223.         }
  224.  
  225.         if(JpegReadWord(file, width) == FALSE)
  226.         {
  227.             return FALSE;
  228.         }
  229.  
  230.         return TRUE;
  231.     }
  232.  
  233.     DEBUG_PRINT(("JFIF SOF marker not found"));
  234.  
  235.     /* didn't find the SOF or found the SOS */
  236.     return FALSE;
  237. }
  238.  
  239.